<?php
namespace bee;
define("DB_DONT_FETCH", 0);
define("DB_FETCH_FIRST_ROW", 1);
define("DB_FETCH_FIRST_VALUE", 2);
define("DB_FETCH_ALL", 3);


/**
 *
 * @author dzelenika
 * @todo riješiti konstantom karakterističnosti pojedinih baza (allmost done)
 * @todo multiple database connection handling
 */
class db extends singleton
{ static protected $__class;
  static protected $__instance;
  public $__NAME_OPEN;
  public $__NAME_CLOSE;
  protected function __construct()
  { try
    { $cfg = config::getInstance();
//die($cfg->sql__USERNAME);
      static::$__class = new \PDO(   $cfg->sql__SERVER,
                        $cfg->sql__USERNAME ,
                        $cfg->sql__PASSWORD);//, array("Database" => $cfg->sql__DB_NAME) );
                        //echo $cfg->sql__DB_NAME;
      static::$__class->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

      if(($cfg->sql__DATABASE_TYPE & DB_ENGINE_MYSQL) == DB_ENGINE_MYSQL)
      { static::$__class->exec("SET NAMES 'UTF8'");
        //static::$__class->exec("SET NOCOUNT ON");
        $this->__NAME_OPEN    = "`";
        $this->__NAME_CLOSE   = "`";
      }
      if(($cfg->sql__DATABASE_TYPE & DB_ENGINE_MSSQL) == DB_ENGINE_MSSQL)
      { static::$__class->exec("SET NOCOUNT ON");//??????
        $this->__NAME_OPEN    = "[";
        $this->__NAME_CLOSE   = "]";
      }
      if(($cfg->sql__DATABASE_TYPE & DB_ENGINE_ORACLE) == DB_ENGINE_ORACLE)
      { $this->__NAME_OPEN    = '"';
        $this->__NAME_CLOSE   = '"';
      }
      //print_r(static::$_class );
    } catch (\PDOException $ex)
    { echo ":: ::" . nl2br(print_r($ex, true)) . ":: ::<br />";
    }
  }
  /**
   *
   * @param $sql
   * @param $fetch_mode
   * @param $pdo_fetch_style
   * @return unknown_type
   */
  public function execSQL(afterWhere $sql, $fetch_mode = DB_FETCH_FIRST_VALUE, $pdo_fetch_style = \PDO::FETCH_BOTH)
  { //echo $sql->text;
    //print_r($sql->getParams());
    $return='';
    $stmt = $this->getInstance()->prepare($sql->text);
    if($stmt->execute($sql->getParams()))
    { if($fetch_mode          == DB_DONT_FETCH)
      { return true;
      } else if($fetch_mode   == DB_FETCH_FIRST_ROW)
      { $return = $stmt->fetch($pdo_fetch_style);
      } else if($fetch_mode   == DB_FETCH_FIRST_VALUE)
      { $row = $stmt->fetch(\PDO::FETCH_NUM);
        return $row[0];
      } else if($fetch_mode   == DB_FETCH_ALL)
      { $return = $stmt->fetchAll($pdo_fetch_style );
      }
    } else
    { return false;
    }
    foreach ($return as &$v)
    { if(is_array($v))
      { foreach ($v as &$av)
        { //$av = iconv("Windows-1250", "UTF-8", $av);
        	//$av = iconv("UTF-16", "UTF-8", $av);
        }
      } else
      { //$v = iconv("Windows-1250", "UTF-8", $v);
      	//$v = iconv("UTF-16", "UTF-8", $v);
      }
    }
    return $return;
  }
  /**
   *
   * @param $DAORow
   * @param $sql
   * @param $fetch_mode
   * @param $pdo_fetch_style
   * @return unknown_type
   */
  public function execSQLByDAORow(DAO $DAORow, afterWhere $sql = NULL, $fetch_mode = DB_FETCH_FIRST_VALUE, $pdo_fetch_style = \PDO::FETCH_BOTH)
  { $where_refl = new \ReflectionClass(get_class($DAORow));
    $cls_props = $where_refl->getProperties(\ReflectionProperty::IS_PUBLIC);
    $query_arr = array();
    $param_array = array();

    foreach($cls_props as $prop)
    { if(!empty($DAORow->{$prop->name}))
      { $query_arr[$prop->name] = $this->__NAME_OPEN . $prop->name . $this->__NAME_CLOSE . " = :" . $prop->name ;// . $daoRow->prepareSQL($daoRow->{$prop->name}, true);
        $param_array[":" .$prop->name] = $DAORow->{$prop->name};
      }
    }

    $sqt = $sql->text . (  $query_arr ? (" AND " . implode(" AND ", $query_arr)) : " ");
    $stmt = $this->getInstance()->prepare($sqt);
    //echo $sqt;
    if($stmt->execute(array_merge($sql->getParams(), $param_array)))
    { if($fetch_mode          == DB_DONT_FETCH)
      { return true;
      } else if($fetch_mode   == DB_FETCH_FIRST_ROW)
      { $return = $stmt->fetch($pdo_fetch_style);
      } else if($fetch_mode   == DB_FETCH_FIRST_VALUE)
      { $row = $stmt->fetch(\PDO::FETCH_NUM);
        return $row[0];
      } else if($fetch_mode   == DB_FETCH_ALL)
      { $return = $stmt->fetchAll($pdo_fetch_style);
      }
    } else
    { return false;
    }
    foreach ($return as &$v)
    { if(is_array($v))
      { foreach ($v as &$av)
        { // //$av = iconv("Windows-1250", "UTF-8", $av);
        }
      } else
      { // //$v = iconv("Windows-1250", "UTF-8", $v);
      }
    }
    return $return;
  }
}
